package com.school.admin.common.utils;

import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import com.school.admin.common.config.SystemConfig;
import com.school.admin.common.handler.GlobalExceptionEnum;
import com.school.admin.common.result.BaseResult;
import com.school.admin.common.result.R;
import com.school.admin.common.result.RedisKeyResult;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author :zzz
 * @date :created in 2020/5/12 16:41
 * @desc :
 */
public class MD5Util {
    static Digester md5 = new Digester(DigestAlgorithm.MD5);

    /**
     * 密码加密
     *
     * @param pass
     * @return
     */
    public static Map<String, String> encryptionPass(String pass) {
        Map<String, String> map = new HashMap<>();
        //加密用户输入密码
        String pss = md5.digestHex(pass);
        //生成加密盐
        String a = SnowflakeUtil.randomLong() + "";
        //加密加密盐
        String salt = md5.digestHex(a);

        //密码密文+加密盐的密文=数据库存储的密码
        String password = md5.digestHex(pss + salt);
        map.put("password", password);
        map.put("salt", salt);
        return map;
    }

    /**
     * 验证密码
     *
     * @param cipherText :数据库存储密文
     * @param salt       :数据库储备盐
     * @param userPass   :用户密码
     */
    public static R verification(String cipherText, String salt, String userPass, Long userId) {
        userPass = md5.digestHex(userPass);
        String mw = md5.digestHex(userPass + salt);
        boolean equals = cipherText.equals(mw);
        String loginKey = BaseResult.RedisKeyResult.WRONG_LOGIN + userId;
        String loginKeyTime = BaseResult.RedisKeyResult.WRONG_LOGIN_TIME + userId;

        if (!equals) {
            boolean aBoolean = RedisKeyResult.redisUtil.hasKey(loginKey);
            if (aBoolean) {
                RedisKeyResult.redisUtil.incrBy(loginKey);
                Object wrongLogin = RedisKeyResult.redisUtil.get(loginKey);
                if (wrongLogin != null) {
                    int wrong = Integer.parseInt(String.valueOf(wrongLogin));
                    //说明登录次数达标
                    if (SystemConfig.allowPasswordMistake < wrong) {
                        RedisKeyResult.redisUtil.set(loginKeyTime, SystemConfig.allowPasswordMistake, SystemConfig.passwordTargetWaitingTime);
                        //删除
                        RedisKeyResult.redisUtil.delete(loginKey);
                        long expire = RedisKeyResult.redisUtil.getExpire(loginKeyTime, TimeUnit.SECONDS);
                        long h = expire / 3600;
                        long m = (expire % 3600) / 60;
                        long s = (expire % 3600) % 60;

                        return R.error(GlobalExceptionEnum.LOGIN_TOO_MANY_ERRORS.getCode(), "您尝试次数过高请" + h + "小时" + m + "分钟" + s + "秒后重试");
                    }
                }
            } else {
                RedisKeyResult.redisUtil.set(loginKey, 1, SystemConfig.passwordTargetWaitingTime);
            }

            Object wrongLogin = RedisKeyResult.redisUtil.get(loginKey);

            int wrong = Integer.parseInt(String.valueOf(wrongLogin));
            if (SystemConfig.allowPasswordMistake - wrong==0) {
                return R.error(GlobalExceptionEnum.LOGIN_TOO_MANY_ERRORS.getCode(),
                        "账号已被锁定");
            }
            return R.error(GlobalExceptionEnum.LOGIN_TOO_MANY_ERRORS.getCode(),
                    "密码错误" + (SystemConfig.allowPasswordMistake - wrong) + "次后将锁定");
        }
        return R.ok();
    }


}
